namespace Base {
    // 1.联合类型： |  取并集
    // type one=string|number;
    // let a1:one="hello";
    // let a2:one=123;

    // type arr1=[number,string];
    // type arr2=[boolean,number];
    // // 数组就是两种数据类型二选一
    // type arr3=arr1 | arr2;
    // let c1:arr3=[1,"2"];
    // let c2:arr3=[true,2];

    // interface obj1{
    //     name:string,
    //     age:number
    // }

    // interface obj2{
    //     height:number,
    //     married:boolean
    // }

    // // 对象取并集，所有属性都可以融合在一起
    // type obj3=obj1|obj2;
    // let p1:obj3={
    //     name:"小米",
    //     age:19,
    //     height:190,
    //     married:true
    // }
    // console.log(p1);



    // 2.交叉类型：&  取交集
    // type two=string | number |boolean;
    // type three=number | undefined;
    // type four=two & three;//number
    // let b1:four=123;

    // type arr1=[number,string];
    // type arr2=[boolean,number];
    // 注意：数组取交集，最后的类型就是never
    // type arr3=arr1&arr2;
    // let x:arr3;
    // console.log(x);

    // interface obj1{
    //     name:string,
    //     age:number
    // }

    // interface obj2{
    //     name:string,
    //     height:number,
    //     married:boolean
    // }

    // // 对象使用&，是对数据类型进行扩展
    // type obj3=obj1&obj2;
    // let p3:obj3={
    //     name:"xiaomi",
    //     age:19,
    //     height:190,
    //     married:true
    // }



    // 3.keyof操作符：用于获取键的联合类型

    // interface obj{
    //     name:string,
    //     age:number,
    //     height:number,
    //     married:boolean
    // }
    // type t1=keyof obj;//"name"|"age"|"height"|"married"
    // let x:t1="married";

    // type t2=keyof string;
    // let x2:t2="localeCompare"
    // type t4=keyof number;

    // type arr=[string,number,boolean,undefined];
    // type t3=keyof arr;//数字类型，因为数组的键就是下标，下标就是数字
    // let x3:t3=12;

    // 约束泛型

    // interface obj {
    //     name: string,
    //     age: number,
    //     height: number,
    //     married: boolean
    // }


    // function fn<T extends "qwe"|123>(a: T) {
    //     return a
    // }

    // console.log(fn("qwe"));

    // extends关键字的用途：
    // 拓展方面： class 类继承、 interface 接⼝拓展
    // 泛型约束： T extends 类型K：表示T类型只能是类型K里面的内容


    // 映射类型
    // 1.{[P in K] : T} 拷⻉
    // type T1={
    //     [P in 'a'|'b'|'c'] :number
    //     // 属性名是'a'|'b'|'c'，属性值都是number类型
    // }

    // 结果：
    // type T1 = {
    //     a: number;
    //     b: number;
    //     c: number;
    // }

    // let p1:T1={
    //     a:1,
    //     b:8,
    //     c:10
    // }


    // 2.{[P in K] ?: T} ⾮必填
    // type T=string|number|boolean
    // type T2={
    //     [P in 'a'|'b'|"c"]?:T
    // }

    // 结果
    // type T2 = {
    //     a?: string|number|boolean;
    //     b?: string|number|boolean;
    //     c?: string|number|boolean;
    // }

    // let p2:T2={
    //     a:"hello",
    //     b:23,
    //     // c:true
    // }


    //  3.{[P in K] -?: T} 必填
    // interface K{
    //     name:string,
    //     age?:number,
    //     height?:number
    // }

    // type T3={
    //     [P in keyof K]-?:string|number
    // }

    // 结果
    // type T3 = {
    //     name: string | number;
    //     age: string | number | undefined;
    //     height: string | number | undefined;
    // }

    // let p3:T3={
    //     name:"xiaomi",
    //     age:19,
    //     height:190
    // }

    // 4.{readonly [P in K] : T} 只读
    // type T4={
    //     readonly [P in 'a'|'b'|'c'] :string|number
    // }

    // type T4 = {
    //     readonly a: string | number;
    //     readonly b: string | number;
    //     readonly c: string | number;
    // }

    // let p4:T4={
    //     a:"hello",
    //     b:19,
    //     c:123
    // }
    // p4.a=666;无法赋值修改，因为是只读属性

    // 5.{readonly[P in K] ?: T} 只读 ⾮必填
    // 6.{-readonly[P in K] ?: T} 没有只读 ⾮必填


    // 条件类型
    // 语法：T extends U ? X : Y
    // type T1=number extends number ? "123" : false;
    // // 结果：type T1 = true
    // let a1:T1="123"

    // type T2=number extends string|number ? "123" :456;
    // // 结果：type T2 = "123"

    // type T3=number extends string ?"123":456;
    // // 结果：type T3 = 456

    // type T4=number|string extends string ? "123":456;
    // // 结果：type T4 = 456

    // type T5=string | number extends string | boolean ? '123':456;
    // // 结果：type T4 = 456

    // type T6=string | number extends string | boolean | number ? '123':456;
    // // 结果：type T6 = "123"

    // TS工具类
    // 1.Partial 所有属性加⾮必填？
    // type Partial<T> = {
    //     [P in keyof T]?: T[P];
    // };

    // interface obj{
    //     name:string,
    //     age:number
    // }

    // type T1=Partial<obj>;
    // 结果
    // type T1 = {
    //     name?: string | undefined;
    //     age?: number | undefined;
    // }

    // 2.Pick 选择属性

    // interface obj{
    //     name:string,
    //     age:number,
    //     height:number
    // }
    // type T2=Pick<obj,'age' | "name">;
    // 结果：
    // type T2 = {
    //     age: number;
    //     name: string;
    // }


    // 3.Required 删除可选，把所有属性都变成必填
    // interface obj{
    //     name:string,
    //     age?:number,
    //     height?:number
    // }
    // type T3=Required<obj>;
    // 结果：
    // type T3 = {
    //     name: string;
    //     age: number;
    //     height: number;
    // }

    // 4.Exclude 排除单个属性
    // type Exclude<T, U> = T extends U ? never : T;

    // number|boolean extends number|string ? never : number;

    // type T4=Exclude<number|boolean,number|string>;
    // 结果：type T4 = boolean

    // interface obj{
    //     name:string,
    //     age?:number,
    //     height?:number
    // }
    // interface obj2{
    //     name:string,
    //     age?:number,
    //     height?:number,
    //     married:boolean
    // }

    // type T4=Exclude<obj,obj2>;

    // type T5=Exclude<'a'|'b'|"c","a">
    // 结果：type T5 = "b" | "c"

    // 5.Omit 去除多个属性
    // type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

    // interface obj{
    //     name:string,
    //     age?:number,
    //     height?:number
    // }
    // type T5=Omit<obj,"name"|"age">;
    // 结果：
    // type T5 = {
    //     height?: number | undefined;
    // }


    // typeof:获取类型
    let p1 = {
        name: '⼩橘猫',
        age: 11,
        arr: [
            { id: 1, hobs: [1, 2, 3, 4], text: '你好啊' },
            { id: 2, hobs: [1, 2, 3, 4], text: '你好啊' },
            { id: 3, hobs: [1, 2, 3, 4], text: '你好啊' },
            { id: 4, hobs: [1, 2, 3, 4], text: '你好啊' },
        ],
    }
    //根据实例 获取类型 对象
    type Person = typeof p1

    function fn(a:number,b:number):number{
        return a+b;
    }

    // 获取函数类型
    type Fn=typeof fn;

    // 获取返回值类型
    type Re=ReturnType<Fn>

    // 获取参数类型：返回一个数组类型
    type Par=Parameters<Fn>



}



